package tt.dz.biz.service.Job;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tt.dz.biz.dao.common.CommonDAO;
import tt.dz.biz.dao.job.JobLockDAO;
import tt.dz.biz.exception.BusinessException;
import tt.dz.common.DzConstants;
import tt.dz.common.DzConstants.bizSysCode;
import tt.dz.common.DzConstants.jobStatus;
import tt.dz.common.LogUtil;
import tt.dz.vo.JobLockVO;

@Service("jobLockService")
public class JobLockService
{
  @Resource(name="jobLockDAO")
  JobLockDAO jobLockDAO;
  @Value("${job.mutexlock.waitcnt}")
  private int waitCnt;
  @Value("${job.mutexlock.waittime}")
  private long waitTime;
  @Resource(name="commonDAO")
  CommonDAO commonDAO;
  
  public JobLockVO updateJobStatusForLock(String jobCode)
  {
    try
    {
      JobLockVO jobvo = new JobLockVO();
      jobvo.setJobCode(jobCode);
      jobvo.setStatus(DzConstants.jobStatus.WAITING.value());
      JobLockVO jobLockVO = this.jobLockDAO.lockJobByCode(jobvo);
      if (null == jobLockVO) {
        return null;
      }
      jobLockVO.setStatus(DzConstants.jobStatus.RUNNING.value());
      if (StringUtils.isBlank(jobLockVO.getMutexCode())) {
        return jobLockVO;
      }
      String[] jobcodes = jobLockVO.getMutexCode().split(",");
      List<String> jobcodeList = Arrays.asList(jobcodes);
      boolean lockFlag = false;
      int i = 0;
      if (this.waitCnt == 0) {
        this.waitCnt = 5;
      }
      if (this.waitTime == 0L) {
        this.waitTime = 10000L;
      }
      while ((!lockFlag) && (i < this.waitCnt))
      {
        lockFlag = updateJobStatusForLock(jobcodeList);
        if (lockFlag) {
          break;
        }
        i++;
        Thread.sleep(this.waitTime);
        LogUtil.info("锁job：" + jobcodeList + "失败：" + i + "次");
      }
      if (!lockFlag) {
        return null;
      }
      this.jobLockDAO.updateJobStatus(jobLockVO);
      int n = this.jobLockDAO.updateJobStatus(DzConstants.jobStatus.PAUSE.value(), jobcodeList);
      if (jobcodes.length != n) {
        throw new BusinessException("updateJobStatusForLock：：更新job数和锁定job数不一致");
      }
      return jobLockVO;
    }
    catch (Exception e)
    {
      LogUtil.error("锁job:" + jobCode + "异常", e);
    }
    return null;
  }
  
  public int updateJobStatusForRestart(JobLockVO jobVO)
  {
    try
    {
      int n = this.jobLockDAO.updateJobStatus(jobVO);
      if (StringUtils.isNotBlank(jobVO.getMutexCode()))
      {
        String[] jobcodes = jobVO.getMutexCode().split(",");
        this.jobLockDAO.updateJobStatus(DzConstants.jobStatus.WAITING.value(), Arrays.asList(jobcodes));
      }
      return n;
    }
    catch (Exception e)
    {
      LogUtil.error("更新job状态异常，参数为：" + jobVO, e);
    }
    return 0;
  }
  
  public boolean updateJobStatusForLock(List jobCodes)
  {
    try
    {
      List<JobLockVO> list = this.jobLockDAO.lockJobByCodes(DzConstants.jobStatus.WAITING.value(), jobCodes);
      if (CollectionUtils.isEmpty(list)) {
        return false;
      }
      if (list.size() != jobCodes.size()) {
        return false;
      }
      for (JobLockVO jobLockVO : list) {
        if (null == jobLockVO) {
          return false;
        }
      }
      return true;
    }
    catch (Exception e)
    {
      LogUtil.error("锁job:" + jobCodes + "异常", e);
    }
    return false;
  }
  
  public int updateLastRunTimeByCode(String jobCode)
    throws Exception
  {
    try
    {
      return this.jobLockDAO.updateLastRunTimeByCode(jobCode);
    }
    catch (Exception e)
    {
      LogUtil.error("更新job本次运行时间异常，参数jobCode为：" + jobCode, e);
      throw e;
    }
  }
  
  public List<JobLockVO> listAllDailyJob()
  {
    List<JobLockVO> jobList = null;
    try
    {
      jobList = this.jobLockDAO.listAllDailyJob();
    }
    catch (Exception e)
    {
      LogUtil.error("查询所有job异常", e);
      jobList = new ArrayList();
    }
    return jobList;
  }
  
  public String querySysCurrentState()
  {
    try
    {
      return this.commonDAO.getCurrentSysState(DzConstants.bizSysCode.MAIN_SERVER.value());
    }
    catch (Exception e)
    {
      LogUtil.error("查询系统当前状态异常", e);
    }
    return "";
  }
  
  public JobLockVO queryJobByCode(String jobCode)
  {
    return this.jobLockDAO.queryJobByCode(jobCode);
  }
}
